package org.unidata.mdm.meta.context;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.unidata.mdm.core.context.AbstractModelChangeContext;
import org.unidata.mdm.core.service.segments.ModelUpsertStartExecutor;
import org.unidata.mdm.meta.configuration.TypeIds;
import org.unidata.mdm.meta.type.model.measurement.MeasurementCategory;
import org.unidata.mdm.meta.util.ModelUtils;

/**
 * @author Mikhail Mikhailov on Oct 8, 2020
 */
public class UpsertMeasurementUnitsContext extends AbstractModelChangeContext {
    /**
     * GSVUID.
     */
    private static final long serialVersionUID = 5287140272593146255L;
    /**
     * Enumerations updates.
     */
    private final List<MeasurementCategory> measurementCategoriesUpdate;
    /**
     * Enumerations deletes.
     */
    private final List<String> measurementCategoriesDelete;
    /**
     * Constructor.
     */
    private UpsertMeasurementUnitsContext(UpsertMeasurementUnitsContextBuilder b) {
        super(b);
        this.measurementCategoriesUpdate = Objects.isNull(b.measurementCategoriesUpdate) ? Collections.emptyList() : b.measurementCategoriesUpdate;
        this.measurementCategoriesDelete = Objects.isNull(b.measurementCategoriesDelete) ? Collections.emptyList() : b.measurementCategoriesDelete;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public String getTypeId() {
        return TypeIds.MEASUREMENT_UNITS_MODEL;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public String getInstanceId() {
        // Enumerations are singletons per storage id
        return ModelUtils.DEFAULT_MODEL_INSTANCE_ID;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public String getStartTypeId() {
        return ModelUpsertStartExecutor.SEGMENT_ID;
    }
    /**
     * @return the enumerationsUpdate
     */
    public List<MeasurementCategory> getMeasurementCategoriesUpdate() {
        return measurementCategoriesUpdate;
    }
    /**
     * @return the enumerationsDelete
     */
    public List<String> getMeasurementCategoriesDelete() {
        return measurementCategoriesDelete;
    }

    public static UpsertMeasurementUnitsContextBuilder builder() {
        return new UpsertMeasurementUnitsContextBuilder();
    }
    /**
     * @author Mikhail Mikhailov on Oct 9, 2020
     */
    public static class UpsertMeasurementUnitsContextBuilder extends AbstractModelChangeContextBuilder<UpsertMeasurementUnitsContextBuilder> {
        /**
         * Enumerations updates.
         */
        private List<MeasurementCategory> measurementCategoriesUpdate;
        /**
         * Enumerations deletes.
         */
        private List<String> measurementCategoriesDelete;
        /**
         * Constructor.
         */
        private UpsertMeasurementUnitsContextBuilder() {
            super();
        }

        public UpsertMeasurementUnitsContextBuilder update(MeasurementCategory... ss) {
            if (ArrayUtils.isNotEmpty(ss)) {
                return update(Arrays.asList(ss));
            }
            return self();
        }

        public UpsertMeasurementUnitsContextBuilder update(Collection<MeasurementCategory> ss) {
            if (CollectionUtils.isNotEmpty(ss)) {
                if (measurementCategoriesUpdate == null) {
                    measurementCategoriesUpdate = new ArrayList<>();
                }

                measurementCategoriesUpdate.addAll(ss);
            }
            return self();
        }

        public UpsertMeasurementUnitsContextBuilder delete(String... ss) {
            if (ArrayUtils.isNotEmpty(ss)) {
                return delete(Arrays.asList(ss));
            }
            return self();
        }

        public UpsertMeasurementUnitsContextBuilder delete(Collection<String> ss) {
            if (CollectionUtils.isNotEmpty(ss)) {
                if (measurementCategoriesDelete == null) {
                    measurementCategoriesDelete = new ArrayList<>();
                }

                measurementCategoriesDelete.addAll(ss);
            }
            return self();
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public UpsertMeasurementUnitsContext build() {
            return new UpsertMeasurementUnitsContext(this);
        }
    }
}
